﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.ServiceModel.Syndication;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Cofe.Web.Utils
{
    //http://www.strathweb.com/2012/04/rss-atom-mediatypeformatter-for-asp-net-webapi/
    public class SyndicationFeedFormatter : MediaTypeFormatter
    {
        private readonly string atom = "application/atom+xml";
        private readonly string rss = "application/rss+xml";
        private readonly string xml = "application/xml";


        public SyndicationFeedFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(atom));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(rss));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue(xml));
        }

        Func<Type, bool> SupportedType = (type) =>
        {
            if (type == typeof(SyndicationItem) || type == typeof(IEnumerable<SyndicationItem>) || type == typeof(SyndicationFeed))
                return true;
            else
                return false;
        };

        public override bool CanReadType(Type type)
        {
            return SupportedType(type);
        }

        public override bool CanWriteType(Type type)
        {
            return SupportedType(type);
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
        {
            return Task.Factory.StartNew(() =>
            {
                if (type == typeof(SyndicationItem) || type == typeof(IEnumerable<SyndicationItem>) || type == typeof(SyndicationFeed))
                    BuildSyndicationFeed(value, writeStream, content.Headers.ContentType.MediaType);
            });
        }

        private void BuildSyndicationFeed(object models, Stream stream, string contenttype)
        {
            

            SyndicationFeed feed;
            if (models is SyndicationFeed)
            {
                feed = (SyndicationFeed)models;
            }
            else
            {
                List<SyndicationItem> items = new List<SyndicationItem>();
                feed = new SyndicationFeed()
                {
                    Title = new TextSyndicationContent("My Feed")
                };

                if (models is IEnumerable<SyndicationItem>)
                {
                    var enumerator = ((IEnumerable<SyndicationItem>)models).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        items.Add(enumerator.Current);
                    }
                }
                else
                {
                    items.Add((SyndicationItem)models);
                }

                feed.Items = items;
            }

            using (XmlWriter writer = XmlWriter.Create(stream))
            {
                if (string.Equals(contenttype, atom))
                {
                    Atom10FeedFormatter atomformatter = new Atom10FeedFormatter(feed);
                    atomformatter.WriteTo(writer);
                }
                else
                {
                    Rss20FeedFormatter rssformatter = new Rss20FeedFormatter(feed);
                    rssformatter.WriteTo(writer);
                }

            }
        }


    }
}
